package com.zxs.product.service.impl;

import client.CartClient;
import client.CategoryClient;
import client.CollectClient;
import client.OrderClient;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.zxs.product.mapper.PictureMapper;
import com.zxs.product.mapper.ProductMapper;
import com.zxs.product.service.ProductService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import parm.*;
import pojo.Picture;
import pojo.Product;
import to.OrderToProduct;
import utils.R;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zxs
 * *7 18:17
 */
@Service
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {


    //引入feign客户端需要,在启动类添加配置注解
    @Autowired
    private CategoryClient categoryClient;
    @Autowired
    private CartClient cartClient;
    @Autowired
    private CollectClient collectClient;
    @Autowired
    private OrderClient orderClient;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private PictureMapper pictureMapper;

    /**
     * 单类别名称 查询热门商品 至多7条数据
     * 1. 根据类别名称 调用 feign客户端访问类别服务获取类别的数据
     * 2. 成功 继续根据类别id查询商品数据  [热门 销售量倒序 查询7]
     * 3. 结果封装即可
     *
     * @param categoryName 类别名称
     * @return r
     */
    //缓存默认1小时
    @Cacheable(value = "list.product",key = "#categoryName")
    @Override
    public R promo(String categoryName) {

        R r = categoryClient.byName(categoryName);

        if (r.getCode().equals(R.FAIL_CODE)) {
            log.info("ProductServiceImpl.promo业务结束，结果:{}", "类别查询失败!");
            return r;
        }

        // 类别服务中 data = category --- feign {json}  ----- product服务 LinkedHashMap jackson

        LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) r.getData();

        Integer categoryId = (Integer) map.get("category_id");
        //封装查询参数
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category_id", categoryId);
        queryWrapper.orderByDesc("product_sales");

        IPage<Product> page = new Page<>(1, 7);

        //返回的是包装数据! 内部有对应的商品集合,也有分页的参数 例如: 总条数 总页数等等
        page = productMapper.selectPage(page, queryWrapper);

        List<Product> productList = page.getRecords(); //指定页的数据
        long total = page.getTotal(); //获取总条数

        log.info("ProductServiceImpl.promo业务结束，结果:{}", productList);

        return R.ok("数据查询成功", productList);
    }

    /**
     * 首页热门类别集合
     * @param productHotParam
     * @return
     */
    @Cacheable(value = "list.product",key = "#productHotParam.categoryName")
    @Override
    public R hots(ProductHotParam productHotParam) {
        R r = categoryClient.hots(productHotParam);

        if (r.getCode().equals(R.FAIL_CODE)) {
            log.info("类别集合不能为空！查询失败!");
            return r;
        }
        //获得类别集合的id集合
        List<Object> ids = (List<Object>) r.getData();

        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("category_id", ids);
        queryWrapper.orderByDesc("product_sales");
        //分割数据
        Page<Product> page = new Page<>(1, 7);
        Page<Product> productPage = productMapper.selectPage(page, queryWrapper);

        //获得当前页的数据
        List<Product> records = productPage.getRecords();
        log.info("ProductServiceImpl.hots业务结束，结果:{}", records);

        return R.ok("多类别热门商品查询成功", records);
    }

    /**
     * 类别集合
     * @return
     */
    @Override
    public R clist() {
        R list = categoryClient.list();
        log.info("类别信息：", list);
        return list;
    }

    /**
     * 根据类别id查询商品
     *
     * @param categoryParamInteger
     * @return
     */
    @Override
    public R bycategory(CategoryParamInteger categoryParamInteger) {
        //获得参数中的id集合 和 分页大小
        List<Integer> categoryID = categoryParamInteger.getCategoryID();
        Integer currentPage = categoryParamInteger.getCurrentPage();
        Integer pageSize = categoryParamInteger.getPageSize();

        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        Page<Product> page = new Page<>(currentPage, pageSize);


        if (!categoryID.isEmpty()) {
            queryWrapper.in("category_id", categoryID);
        }
        //如果queryWrapper 为空，则查询全部
        Page<Product> productPage = productMapper.selectPage(page, queryWrapper);
        List<Product> records = productPage.getRecords();
        long total = productPage.getTotal();

        //封装结果集
        R ok = R.ok("类别商品查询成功！", records, total);

        return ok;
    }

    /**
     * 根据商品 id查询某个商品的详情信息
     *
     * @param productID
     * @return
     */
    @Override
    public R detail(Integer productID) {
        Product product = productMapper.selectById(productID);
        R ok = R.ok("商品详情查询成功", product);
        return ok;
    }

    /**
     * 收藏集合
     * @param productIds
     * @return
     */
    @Override
    public R collectList(List<Integer> productIds) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("product_id", productIds);

        List<Product> products = productMapper.selectList(queryWrapper);
        R ok = R.ok("收藏列表如下：", products);
        return ok;
    }

    /**
     * 返回购物车需要的商品集合
     *
     * @param productIds
     * @return
     */
    @Override
    public List<Product> cartList(List<Integer> productIds) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();

        queryWrapper.in("product_id", productIds);

        List<Product> products = productMapper.selectList(queryWrapper);

        return products;
    }

    /**
     * 修改库存和增加销售量
     *
     * @param orderToProductList
     */
    @Transactional
    @Override
    public void subNumber(List<OrderToProduct> orderToProductList) {

        //将productNumberParams转成map
        //使用id作为key, item做值, 比较相邻的两次key,如果相同,去掉重读!
        Map<Integer, OrderToProduct> orderToProductListMap = orderToProductList.stream()
                .collect(Collectors.toMap(OrderToProduct::getProductId, v -> v));

        //封装商品id集合
        Set<Integer> productIds = orderToProductListMap.keySet();

        //查询商品集合
        List<Product> productList = baseMapper.selectBatchIds(productIds);
        //修改

        for (Product product : productList) {
            //设置新库存
            product.setProductNum(product.getProductNum() -
                    orderToProductListMap.get(product.getProductId()).getProductNum());
            //设置销售量
            product.setProductSales(product.getProductSales() +
                    orderToProductListMap.get(product.getProductId()).getProductNum());
        }

        //商品的库存和销量在集合productList当中已被修改，然后在数据库批量数据更新
        this.updateBatchById(productList);
    }

    /**
     * 后台调用商品数据
     *
     * @return
     */
    @Override
    public R getProducts(PageParam pageParam) {

        Page<Product> page = new Page<>(pageParam.getCurrentPage(), pageParam.getPageSize());
        Page<Product> productPage = productMapper.selectPage(page, null);
        List<Product> records = productPage.getRecords();
        long total = productPage.getTotal();
        return R.ok("查询全部商品成功", records, total);
    }

    /**
     * 后台修改商品信息
     *
     * @param product
     * @return
     */
    @Override
    public R update(Product product) {

        int rows = productMapper.updateById(product);

        if (rows == 0) {
            return R.fail("商品数据更新失败!");
        }
        return R.ok("商品数据更新成功!");
    }

    /**
     * 后台保存商品
     *
     * @param productSaveParam
     * @return
     */
    @Override
    public R adminSave(ProductSaveParam productSaveParam) {
        Product product = new Product();
        //参数赋值
        BeanUtils.copyProperties(productSaveParam, product);

        //商品数据保存
        int rows = productMapper.insert(product);

        if (rows == 0) {
            return R.fail("商品保存失败!");
        }
        //进行Picture对象封装
        String pictures = productSaveParam.getPictures();
        System.out.println("pictures = " + pictures);

        if (!StringUtils.isEmpty(pictures)) {
            //$ + - * | / ？^符号在正则表达示中有相应的不同意义。
            //一般来讲只需要加[]、或是\\即可
            String[] pics = pictures.split("[+]");
            for (String pic : pics) {
                Picture picture = new Picture();
                picture.setIntro(null);
                picture.setProductId(product.getProductId());
                picture.setProductPicture(pic);
                //因为没有复用业务,无法使用mybatis-plus批量插入
                int i = pictureMapper.insert(picture);
                if (i == 0) {
                    return R.fail("商品保存失败!");
                }
            }
        }
        return R.ok("商品数据保存成功!");
    }

    /**
     * 后台删除商品
     * @param productId
     * @return
     */
    @Override
    public R adminDelete(Integer productId) {
        //1.检查购物车是否存在
        R r = cartClient.checkProduct(productId);

        if ("004".equals(r.getCode())) {
            log.info("ProductServiceImpl.remove结束,{}", r.getMsg());
            return r;
        }
        //2 检查账单是否存在
        R order = orderClient.check(productId);
        if ("004".equals(order.getCode())) {
            log.info("ProductServiceImpl.remove结束,{}", order.getMsg());
            return order;
        }

        //删除商品图片详情
        QueryWrapper<Picture> wrapper = new QueryWrapper<>();
        wrapper.eq("product_id", productId);
        pictureMapper.delete(wrapper);
        //删除收藏中的商品
        collectClient.removeByPID(productId);

        //3.删除商品数据 和 删除商品对应的图片数据
        int rows = productMapper.deleteById(productId);

        if (rows == 0) {
            log.info("ProductServiceImpl.remove业务结束，结果:{}", "商品删除失败!");
            return R.fail("商品删除失败!");
        }
        R ok = R.ok("商品数据删除成功!");
        log.info("ProductServiceImpl.remove业务结束，结果:{}", ok);
        return ok;
    }


    @Override
    public R search(ProductParamsSearch productParamsSearch) {
        String search = productParamsSearch.getSearch();
        int currentPage = productParamsSearch.getCurrentPage();
        int pageSize = productParamsSearch.getPageSize();
        Page<Product> productPage = new Page<Product>(currentPage,pageSize);
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Product> wrapper = queryWrapper.like(Product::getProductName, search)
                .or().like(Product::getProductIntro, search)
                .or().like(Product::getProductTitle, search);
        Page<Product> page = productMapper.selectPage(productPage, wrapper);
        List<Product> records = page.getRecords();
        long total = page.getTotal();
        return R.ok("搜索成功！",records,total);
    }
}

